{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "AIDungeon 2.ipynb",
      "provenance": [],
      "collapsed_sections": [],
      "toc_visible": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "pdmJ358wwzmv"
      },
      "source": [
        "![BYU PCCL](https://pcc4318.files.wordpress.com/2018/02/asset-1.png?w=150)\n",
        "\n",
        "Sponsored by the BYU PCCL Lab.\n",
        "\n",
        "> AI Dungeon 2 is a completely AI generated text adventure built with OpenAI's largest GPT-2 model. It's a first of it's kind game that allows you to enter and will react to any action you can imagine.\n",
        "\n",
        "# What is this?\n",
        "Google Colab is a way to experience machine learning for free. Google provides GPUs that you can run code in. Because this game exploded however, Google likely won't be able to allow free usage of it for AI Dungeon for very long. We are almost done making an app version of the game where you will be able to play AI Dungeon 2. Until that's released you can still play the game here.\n",
        "\n",
        "# Main mirrors of AI Dungeon 2 are currently down due to high download costs.\n",
        "We are using bittorrent as a temporary solution to host game files and keep this game alive. It's not fast, but it's the best we've got right now.\n",
        "\n",
        "If you want to help, best thing you can do is to **[download this torrent file with game files](https://github.com/nickwalton/AIDungeon/files/3935881/model_v5.torrent.zip)** and **seed it** indefinitely to the best of your ability. This will help new players download this game faster, and discover the vast worlds of AIDungeon2!\n",
        "\n",
        "- <a href=\"https://twitter.com/nickwalton00?ref_src=twsrc%5Etfw\" class=\"twitter-follow-button\" data-show-count=\"false\">Follow @nickwalton00</a> on Twitter for updates on when it will be available again.\n",
        "- **[Support AI Dungeon 2](https://www.patreon.com/AIDungeon) on Patreon to help me to continue improving the game with all the awesome ideas I have for its future!**\n",
        "\n",
        "## How to play\n",
        "1. Click \"Tools\"-> \"Settings...\" -> \"Theme\" -> \"Dark\" (optional but recommended)\n",
        "2. Go to **Main Game** section below\n",
        "3. Run Install block\n",
        "3. Run Download Model block \n",
        "4. It will then take a couple minutes to boot up as the model is downloaded loaded onto the GPU. \n",
        "5. Run the game block \n",
        "6. If you have questions about getting it to work then please [go to github repo](https://github.com/AIDungeon/AIDungeon) to get help. \n",
        "\n",
        "## About\n",
        "- While you wait you can [read adventures others have had](https://aidungeon.io/)\n",
        "- [Read more](https://pcc.cs.byu.edu/2019/11/21/ai-dungeon-2-creating-infinitely-generated-text-adventures-with-deep-learning-language-models/) about how AI Dungeon 2 is made.\n",
        "- **[Support AI Dungeon 2](https://www.patreon.com/bePatron?u=19115449) on Patreon to help me to continue improving the game with all the awesome ideas I have for its future!**"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "pyNN-3UDv0L-"
      },
      "source": [
        "# Main Game"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 0,
      "metadata": {
        "colab": {},
        "colab_type": "code",
        "id": "FKqlSCrpS9dH"
      },
      "outputs": [],
      "source": [
        "# Install\n",
        "!git clone --depth 1 --branch master https://github.com/AIDungeon/AIDungeon/\n",
        "%cd AIDungeon\n",
        "!./install.sh\n",
        "from IPython.display import clear_output\n",
        "clear_output()\n",
        "print(\"Installation Complete!\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 0,
      "metadata": {
        "colab": {},
        "colab_type": "code",
        "id": "fiywfTj--_Pe"
      },
      "outputs": [],
      "source": [
        "# Download model from torrent:\n",
        "!./download_model.sh\n",
        "from IPython.display import clear_output\n",
        "clear_output()\n",
        "print(\"Download Complete!\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 0,
      "metadata": {
        "colab": {},
        "colab_type": "code",
        "id": "YjArwbWh6XwN"
      },
      "outputs": [],
      "source": [
        "# Play\n",
        "from IPython.display import Javascript\n",
        "display(Javascript('''google.colab.output.setIframeHeight(0, true, {maxHeight: 5000})'''))\n",
        "!source ./venv/bin/activate\n",
        "!./venv/bin/python play.py"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "kIldfwd8wjvT"
      },
      "source": [
        "# Utilities (Persistent Save / Load, OOM Fix)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 0,
      "metadata": {
        "colab": {},
        "colab_type": "code",
        "id": "zLx1yMu9wwBg"
      },
      "outputs": [],
      "source": [
        "# RUN THIS FIRST before running any block below.\n",
        "# This block mount Google Drive to our workspace \n",
        "# so we can save to and load from it!\n",
        "\n",
        "import pathlib\n",
        "from distutils.dir_util import copy_tree\n",
        "from google.colab import drive\n",
        "\n",
        "drive.mount('/content/drive')\n",
        "\n",
        "drive_stories_directory=\"/content/drive/My Drive/AIDungeon/saved_stories\"\n",
        "colab_stories_directory=\"/content/AIDungeon/saved_stories\"\n",
        "\n",
        "drive_model_directory=\"/content/drive/My Drive/Data/model_v5\"\n",
        "colab_model_directory=\"/content/AIDungeon/generator/gpt2/models/model_v5\"\n",
        "\n",
        "pathlib.Path(drive_stories_directory).mkdir(parents=True, exist_ok=True) "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 0,
      "metadata": {
        "colab": {},
        "colab_type": "code",
        "id": "LWfm6q8tAbDB"
      },
      "outputs": [],
      "source": [
        "# Save stories to your Google Drive\n",
        "copy_tree(\n",
        "    colab_stories_directory, \n",
        "    drive_stories_directory\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 0,
      "metadata": {
        "colab": {},
        "colab_type": "code",
        "id": "HK2DO1jFxnv6"
      },
      "outputs": [],
      "source": [
        "# Load stories from your Google Drive\n",
        "copy_tree(\n",
        "    drive_stories_directory, \n",
        "    colab_stories_directory\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 0,
      "metadata": {
        "colab": {},
        "colab_type": "code",
        "id": "Ue0qY7mvKrZ0"
      },
      "outputs": [],
      "source": [
        "# Backup model from Colab to Google Drive. Requires 6.5GB of space!\n",
        "copy_tree(\n",
        "    colab_model_directory,\n",
        "    drive_model_directory\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 0,
      "metadata": {
        "colab": {},
        "colab_type": "code",
        "id": "XqK7MXhG40Oa"
      },
      "outputs": [],
      "source": [
        "# Copy model from Google Drive. Make sure the model is uploaded to your personal Drive. \n",
        "# It should resides in a Data folder. The path is: /Data/model_v5/\n",
        "copy_tree(\n",
        "    drive_model_directory, \n",
        "    colab_model_directory\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [
        {
          "evalue": "Error: Jupyter cannot be started. Error attempting to locate jupyter: Error: Module 'notebook' not installed.",
          "output_type": "error"
        }
      ],
      "source": [
        "# If you get an OOM (out of memory error, random crashes) \n",
        "# you might want to increase the available RAM. \n",
        "\n",
        "# To do so, run this block. Wait until it crashes\n",
        "# and a little message will pops up asking if \n",
        "# you'd like to increase the available memory. Say yes and run the game.\n",
        "# Credit goes to bpseudopod for figuring this out.\n",
        "# Source: https://www.reddit.com/r/AIDungeon/comments/e782oi/tips_for_crash_prevention/\n",
        "\n",
        "d = []\n",
        "while True:\n",
        "    d.append(1)"
      ]
    }
  ]
}
